package com.tarena.lbs.activity.service.impl;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import com.tarena.lbs.activity.dao.repository.ActivityRepository;
import com.tarena.lbs.activity.pojo.param.ActivityAddParam;
import com.tarena.lbs.activity.pojo.param.ActivityUpdateStatusParam;
import com.tarena.lbs.activity.pojo.po.ActivityPO;
import com.tarena.lbs.activity.pojo.query.ActivityQuery;
import com.tarena.lbs.activity.pojo.vo.ActivityVO;
import com.tarena.lbs.activity.service.ActivityService;
import com.tarena.lbs.activity.enums.ActivityStatusEnum;
import com.tarena.lbs.attach.api.AttachApi;
import com.tarena.lbs.attach.pojo.dto.AttachDTO;
import com.tarena.lbs.base.protocol.exception.BusinessException;
import com.tarena.lbs.base.protocol.pager.PageResult;
import com.tarena.lbs.common.utils.AuthenticationContextUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Slf4j
@Service
public class ActivityServiceImpl implements ActivityService {

    @Autowired
    private ActivityRepository activityRepository;

    @DubboReference
    private AttachApi attachApi;


    /**
     * 分页查询活动列表
     * 从认证上下文获取当前商家ID并设置到查询参数中
     * @param query 查询参数
     * @return 活动列表分页结果
     */
    @Override
    public PageResult<ActivityVO> pageList(ActivityQuery query) throws BusinessException {
        try {
            // 设置商家ID，从认证上下文获取
            query.setBusinessId(AuthenticationContextUtils.get().getId());
            log.info("查询活动列表，参数：{}", query);
            PageResult<ActivityVO> pageResult = activityRepository.pageList(query);
            return pageResult;
        } catch (Exception e) {
            log.error("查询活动列表失败", e);
            throw new BusinessException("500","查询活动列表失败");
        }
    }

    /**
     * 保存活动信息
     * 根据参数中是否包含ID来判断是新增还是更新操作
     * @param param 活动参数
     * @throws ParseException 日期解析异常
     */
    @Override
    public void saveActivity(ActivityAddParam param) throws ParseException, BusinessException {
        try {
            log.info("保存活动信息，参数：{}", param);
            // 设置商家ID，从认证上下文获取
            param.setBusinessId(AuthenticationContextUtils.get().getId());
            
            // 业务参数校验
            validateActivityParam(param);
            
            // 转换参数为PO对象
            ActivityPO activityPO = convertToPO(param);
            
            if (param.getId() != null) {
                // 更新活动
                log.info("更新活动，ID：{}", param.getId());
                activityRepository.updateActivity(activityPO);
            } else {
                // 添加活动
                log.info("新增活动：{}", activityPO.getActivityName());
                activityPO.setCreateAt(new Date());
                // 设置初始状态：未启用
                activityPO.setEnableStatus(0);
                // 设置活动状态：未开始
                activityPO.setStatus(0);
                activityRepository.addActivity(activityPO);
            }
        } catch (ParseException e) {
            log.error("日期解析异常", e);
            throw e;
        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            log.error("保存活动失败", e);
            throw new BusinessException("500","保存活动失败");
        }
    }
    
    /**
     * 校验活动参数的业务逻辑合理性
     * @param param 活动参数
     */
    private void validateActivityParam(ActivityAddParam param) throws BusinessException {
        // 校验活动名称
        if (param.getActivityName() == null || param.getActivityName().trim().isEmpty()) {
            throw new BusinessException("400","活动名称不能为空");
        }
        
        // 校验开始时间和结束时间逻辑
        if (param.getStartDate() != null && param.getEndDate() != null) {
            try {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Date startDate = sdf.parse(param.getStartDate());
                Date endDate = sdf.parse(param.getEndDate());
                if (startDate.after(endDate)) {
                    throw new BusinessException("400","开始时间不能晚于结束时间");
                }
            } catch (ParseException e) {
                // 日期格式错误需要向上抛出
                throw new BusinessException("400","日期格式错误，请检查开始时间和结束时间");
            }
        }
        
        // 校验活动说明
        if (param.getDescribes() == null || param.getDescribes().trim().isEmpty()) {
            throw new BusinessException("400","活动说明不能为空");
        }
        
        // 校验活动目标
        if (param.getActivityTarget() == null || param.getActivityTarget().trim().isEmpty()) {
            throw new BusinessException("400","活动目标不能为空");
        }
    }

    /**
     * 根据ID查询活动详情
     * 确保查询的活动属于当前商家
     * @param id 活动ID
     * @return 活动详情VO对象
     */
    @Override
    public ActivityVO getActivityById(Long id) throws BusinessException {
        try {
            log.info("查询活动详情，ID：{}", id);
            Integer businessId = AuthenticationContextUtils.get().getId();
            ActivityPO activityPO = activityRepository.getActivityById(id, businessId);
            if (activityPO == null) {
                log.warn("活动不存在，ID：{}", id);
                throw new BusinessException("400","活动不存在");
            }
            return convertToVO(activityPO);
        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            log.error("查询活动详情失败", e);
            throw new BusinessException("500","查询活动详情失败");
        }
    }

    /**
     * 检查用户是否满足活动目标人群范围
     * 验证活动是否存在、是否启用、是否在有效期内、用户是否在目标人群中
     * @param userId 用户ID
     * @param activityId 活动ID
     * @return true表示满足，false表示不满足
     */
    @Override
    public Boolean activityVisible(Integer userId, Long activityId) {
        try {
            log.info("检查用户是否满足活动目标人群范围，userId={}, activityId={}", userId, activityId);
            // 查询活动信息
            ActivityPO activityPO = activityRepository.getActivityById(activityId, null);
            if (activityPO == null) {
                log.warn("活动不存在，activityId={}", activityId);
                return false;
            }

            // 检查活动状态
            if (!ActivityStatusEnum.ENABLE.getCode().equals(activityPO.getEnableStatus())) {
                log.info("活动未启用，activityId={}", activityId);
                return false;
            }

            // 检查活动时间
            Date now = new Date();
            if (activityPO.getStartDate() == null || activityPO.getEndDate() == null) {
                log.info("活动时间设置不完整，activityId={}", activityId);
                return false;
            }
            if (now.before(activityPO.getStartDate()) || now.after(activityPO.getEndDate())) {
                log.info("活动不在有效期内，activityId={}", activityId);
                return false;
            }

            // 检查目标人群
            String targetCustomer = activityPO.getTargetCustomer();
            if (targetCustomer != null && !targetCustomer.isEmpty()) {
                //TODO 检查用户ID是否在目标人群中
//                String[] customerIds = targetCustomer.split(",");
//                for (String customerId : customerIds) {
//                    if (userId.toString().equals(customerId.trim())) {
//                        return true;
//                    }
//                }
//                log.info("用户不在活动目标人群中，userId={}, activityId={}", userId, activityId);
//                return false;
                return true;
            }

            // 如果没有设置目标人群，则默认所有用户可见
            return true;
        } catch (Exception e) {
            log.error("检查用户是否满足活动目标人群范围失败", e);
            return false;
        }
    }

    /**
     * 转换活动PO对象为VO对象
     * 用于将数据库实体对象转换为前端展示对象
     * @param activityPO 活动PO对象
     * @return 活动VO对象
     */
    @Override
    public ActivityVO convertToVO(ActivityPO activityPO) {
        if (activityPO == null) {
            return null;
        }
        ActivityVO activityVO = new ActivityVO();
        BeanUtils.copyProperties(activityPO, activityVO);
        // 这里可以根据需要添加额外的转换逻辑，例如图片URL处理等
        activityVO.setId(activityPO.getId().intValue());
        activityVO.setRewardCouponId(Integer.valueOf(activityPO.getRewardCouponId()));
        String[] imgIds = activityPO.getImgIds().split(",");
        List<Integer> imgIdsList = new ArrayList<>();
        for (String imgId : imgIds) {
            imgIdsList.add(Integer.valueOf(imgId.trim()));
        }
        List<AttachDTO> imgPics = attachApi.batchGetAttachInfo(imgIdsList, 1);
        List<String> imgPicUrls = new ArrayList<>();
        for (AttachDTO imgPic : imgPics) {
            imgPicUrls.add("http://localhost:9081/static/" + imgPic.getFileUuid());
        }
        activityVO.setImgPics(imgPicUrls);
        log.info("转换活动PO对象为VO对象成功，activityPO={}", activityPO);
        return activityVO;
    }

    /**
     * 转换活动添加参数为PO对象
     * 处理日期格式转换和通用字段设置
     * @param param 活动添加参数
     * @return 活动PO对象
     * @throws ParseException 日期解析异常
     */
    @Override
    public ActivityPO convertToPO(ActivityAddParam param) throws ParseException {
        if (param == null) {
            return null;
        }
        ActivityPO activityPO = new ActivityPO();
        BeanUtils.copyProperties(param, activityPO);
        
        // 转换日期格式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        if (param.getStartDate() != null && !param.getStartDate().isEmpty()) {
            activityPO.setStartDate(sdf.parse(param.getStartDate()));
        }
        if (param.getEndDate() != null && !param.getEndDate().isEmpty()) {
            activityPO.setEndDate(sdf.parse(param.getEndDate()));
        }
        
        // 设置更新时间
        activityPO.setUpdateAt(new Date());
        
        // 设置默认活动类型为赠领
        if (activityPO.getActivityType() == null) {
            activityPO.setActivityType(1);
        }
        
        return activityPO;
    }
    
    /**
     * 启用/禁用活动
     * 验证活动是否存在、是否属于当前商家，然后更新启用状态
     * @param id 活动ID
     * @param enableStatus 启用状态（0：禁用，1：启用）
     */
    @Override
    public void enableActivity(Long id, Integer enableStatus) throws BusinessException {
        try {
            log.info("启用/禁用活动，ID：{}, enableStatus：{}", id, enableStatus);
            Integer businessId = AuthenticationContextUtils.get().getId();
            
            // 验证活动是否存在且属于当前商家
            ActivityPO activityPO = activityRepository.getActivityById(id, businessId);
            if (activityPO == null) {
                log.warn("活动不存在或不属于当前商家，ID：{}", id);
                throw new BusinessException("400","活动不存在或无权限操作");
            }
            
            // 更新启用状态
            activityPO.setEnableStatus(enableStatus);
            activityPO.setUpdateAt(new Date());
            activityRepository.updateActivity(activityPO);
            
            log.info("启用/禁用活动成功，ID：{}", id);
        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            log.error("启用/禁用活动失败", e);
            throw new BusinessException("500","启用/禁用活动失败");
        }
    }

    @Override
    public List<ActivityPO> getActivityListByStoreId(Integer storeId) {
        return activityRepository.getActivityListByStoreId(storeId);
    }
}
